package cz.semjobKB.triples.stat;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import cz.semjobKB.conllx.api.ISentence;
import cz.semjobKB.conllx.api.IWord;
import cz.semjobKB.conllx.api.impl.Document;
import cz.semjobKB.conllx.node.EConstituent;


public class PredicateSons {

	List<IWord> predicateSons = new ArrayList<IWord>();
	Integer total = 0;
	
	public void getPredicateSons (Document doc) {


		for (ISentence sentence : doc.getSentences()) {

			for (IWord word : sentence.getWords()) {

				if (word.getConstituent() == EConstituent.PREDICATE || word.getConstituent() == EConstituent.PREDICATE_NOMINAL) {
					total++;
					int possition = sentence.getWords().indexOf(word) + 1;

					for (IWord possibleSons : sentence.getWords()) {
						if (possibleSons.getParentNode() == possition) {
							predicateSons.add(possibleSons);
						}
					}
				}
			}

		}

	}

	public String mergeAndSort () {

		HashMap<String, Integer> MergeSons = new HashMap<String, Integer>();

		String result =  total.toString() + "\n";
		for (IWord word : predicateSons) {			
			if (MergeSons.containsKey(word.getConstituent().toString())) {
				MergeSons.put(word.getConstituent().toString(), MergeSons.get(word.getConstituent().toString()) + 1);
			} else {
				MergeSons.put(word.getConstituent().toString(), 1);
			}
		}

		MergeSons = sortByValue(MergeSons);

		for (Entry<String, Integer> entry : MergeSons.entrySet()) {
			result += entry.getKey()+ "\t" + entry.getValue().toString() + "\n";
		}

		return result;
	}

	public static <K, V extends Comparable<? super V>> HashMap<K, V> sortByValue(Map<K, V> map) 
	{
		@SuppressWarnings("unchecked")
		Map.Entry<K,V>[] array = map.entrySet().toArray(new Map.Entry[map.size()]);

		Arrays.sort(array, new Comparator<Map.Entry<K, V>>() 
				{
			public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) 
			{
				return e2.getValue().compareTo(e1.getValue());
			}
				});

		HashMap<K, V> result = new LinkedHashMap<K, V>();
		for (Map.Entry<K, V> entry : array)
			result.put(entry.getKey(), entry.getValue());

		return result;
	}
}
